use std::{error, fmt, result};

#[derive(Debug)]
pub enum Error {
    /// 越界错误
    /// 比如:
    /// rva 没有出现在 headers 和 sections 中
    Bounds,
    /// 零填充区错误
    /// 这个发生在 pe 文件中 VirtualSize > SizeOfRawData 时,
    /// 在 ImageBuffer 状态下, 系统拉伸 pe 文件, VirtualSize 多出来的部分被 0 填充.
    /// 我们去引用这部分的地址时就触发这个错误.
    /// 可以看下 Pe trait 中的 rva_to_foa() 方法
    ZeroFill,
    /// 溢出错误
    Overflow,
    /// 地址无法映射错误
    /// 一般出现在 foa 转 rva 时, 当文件地址指向 VirtualSize 和 SizeOfRawData 之间时,
    /// 这块地方是和内存映像没有映射关系的.
    Unmapped,
}

impl Error {
    fn to_str(&self) -> &'static str {
        match self {
            Error::Bounds => "Error::Bounds 越界错误",
            Error::ZeroFill => "Error::ZeroFill 零填充区错误",
            Error::Overflow => "Error::Overflow 溢出错误",
            Error::Unmapped => "Error::Unmapped 无法映射错误",
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.to_str())
    }
}

impl error::Error for Error {}

pub type Result<T> = result::Result<T, Error>;
